From 5bafc17b79d89c922d1cebe820357c2e71f5fc7b Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20H=C3=A4rdeman?= Date: Mon, 6 Oct 2025 14:03:34 +0200 Subject: [PATCH] dhcpv4: use iovec for leasetime/renew/rebind MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Move some more options over to use an iovec. Note that the FIXME will be addressed in a later patch. Signed-off-by: David Härdeman Link: https://github.com/openwrt/odhcpd/pull/278 Signed-off-by: Álvaro Fernández Rojas --- src/dhcpv4.c | 62 ++++++++++++++++++++++++++++++++++++++-------------- src/dhcpv4.h | 1 + 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/dhcpv4.c b/src/dhcpv4.c index 2a5a1d0..8a0d124 100644 --- a/src/dhcpv4.c +++ b/src/dhcpv4.c @@ -623,6 +623,9 @@ enum { IOV_SERVERID, IOV_NTP, IOV_NTP_ADDR, + IOV_LEASETIME, + IOV_RENEW, + IOV_REBIND, IOV_DNR, IOV_DNR_BODY, IOV_END, @@ -672,6 +675,18 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, .code = DHCPV4_OPT_NTPSERVER, .len = iface->dhcpv4_ntp_cnt * sizeof(*iface->dhcpv4_ntp), }; + struct dhcpv4_option_u32 reply_leasetime = { + .code = DHCPV4_OPT_LEASETIME, + .len = sizeof(uint32_t), + }; + struct dhcpv4_option_u32 reply_renew = { + .code = DHCPV4_OPT_RENEW, + .len = sizeof(uint32_t), + }; + struct dhcpv4_option_u32 reply_rebind = { + .code = DHCPV4_OPT_REBIND, + .len = sizeof(uint32_t), + }; struct dhcpv4_option reply_dnr = { .code = DHCPV4_OPT_DNR, }; @@ -685,6 +700,9 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, [IOV_SERVERID] = { &reply_serverid, sizeof(reply_serverid) }, [IOV_NTP] = { &reply_ntp, 0 }, [IOV_NTP_ADDR] = { iface->dhcpv4_ntp, 0 }, + [IOV_LEASETIME] = { &reply_leasetime, 0 }, + [IOV_RENEW] = { &reply_renew, 0 }, + [IOV_REBIND] = { &reply_rebind, 0 }, [IOV_DNR] = { &reply_dnr, 0 }, [IOV_DNR_BODY] = { NULL, 0 }, [IOV_END] = { &reply_end, sizeof(reply_end) }, @@ -838,25 +856,13 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, reply_opts = alloca(req_opts_len + 32); - if (a) { - uint32_t val; + reply_opts[reply_opts_len++] = DHCPV4_OPT_LEASETIME; + reply_opts[reply_opts_len++] = DHCPV4_OPT_RENEW; + reply_opts[reply_opts_len++] = DHCPV4_OPT_REBIND; + if (a) { reply.yiaddr.s_addr = a->addr; - val = htonl(req_leasetime); - dhcpv4_put(&reply, &cursor, DHCPV4_OPT_LEASETIME, 4, &val); - reply_opts[reply_opts_len++] = DHCPV4_OPT_LEASETIME; - - if (req_leasetime != UINT32_MAX) { - val = htonl(500 * req_leasetime / 1000); - dhcpv4_put(&reply, &cursor, DHCPV4_OPT_RENEW, 4, &val); - reply_opts[reply_opts_len++] = DHCPV4_OPT_RENEW; - - val = htonl(875 * req_leasetime / 1000); - dhcpv4_put(&reply, &cursor, DHCPV4_OPT_REBIND, 4, &val); - reply_opts[reply_opts_len++] = DHCPV4_OPT_REBIND; - } - dhcpv4_put(&reply, &cursor, DHCPV4_OPT_NETMASK, 4, &iface->dhcpv4_mask.s_addr); reply_opts[reply_opts_len++] = DHCPV4_OPT_NETMASK; @@ -945,6 +951,27 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, iov[IOV_NTP_ADDR].iov_len = iface->dhcpv4_ntp_cnt * sizeof(*iface->dhcpv4_ntp); break; + case DHCPV4_OPT_LEASETIME: + if (!a) + break; + reply_leasetime.data = htonl(req_leasetime); + iov[IOV_LEASETIME].iov_len = sizeof(reply_leasetime); + break; + + case DHCPV4_OPT_RENEW: + if (!a || req_leasetime == UINT32_MAX) + break; + reply_renew.data = htonl(500 * req_leasetime / 1000); + iov[IOV_RENEW].iov_len = sizeof(reply_renew); + break; + + case DHCPV4_OPT_REBIND: + if (!a || req_leasetime == UINT32_MAX) + break; + reply_rebind.data = htonl(875 * req_leasetime / 1000); + iov[IOV_REBIND].iov_len = sizeof(reply_rebind); + break; + case DHCPV4_OPT_DNR: struct dhcpv4_dnr *dnrs; size_t dnrs_len = 0; @@ -1018,7 +1045,8 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, dhcpv4_set_dest_addr(iface, reply_msg.data, req, &reply, src_addr, &dest_addr); - iov[IOV_HEADER].iov_len = PACKET_SIZE(&reply, cursor); + /* FIXME: check for DHCPV4_MIN_PACKET_SIZE */ + iov[IOV_HEADER].iov_len = (size_t)(cursor - (uint8_t *)&reply); if (send_reply(iov, ARRAY_SIZE(iov), (struct sockaddr *)&dest_addr, sizeof(dest_addr), opaque) < 0) error("Failed to send %s to %s - %s: %m", diff --git a/src/dhcpv4.h b/src/dhcpv4.h index 089a626..c1dc136 100644 --- a/src/dhcpv4.h +++ b/src/dhcpv4.h @@ -19,6 +19,7 @@ #define DHCPV4_FLAG_BROADCAST 0x8000 +// RFC951, §3; RFC1542, §2.1; RFC2131, §2 #define DHCPV4_MIN_PACKET_SIZE 300 #define DHCPV4_FR_MIN_DELAY 500 -- 2.30.2